package com.kexio.dynamic.permission.engine;

import java.util.Map;

/**
 * 权限引擎接口
 * 
 * 定义权限验证的核心接口，支持多种权限验证策略
 * 
 * @author Kexio
 * @since 1.0.0
 */
public interface PermissionEngine {

    /**
     * 检查权限
     * 
     * @param userId   用户ID
     * @param resource 资源标识
     * @param action   操作动作
     * @return 是否有权限
     */
    boolean checkPermission(Long userId, String resource, String action);

    /**
     * 检查权限（带上下文）
     * 
     * @param userId   用户ID
     * @param resource 资源标识
     * @param action   操作动作
     * @param context  上下文参数
     * @return 是否有权限
     */
    boolean checkPermission(Long userId, String resource, String action, Map<String, Object> context);

    /**
     * 检查权限（带条件）
     * 
     * @param userId    用户ID
     * @param resource  资源标识
     * @param action    操作动作
     * @param condition 权限条件表达式
     * @param context   上下文参数
     * @return 是否有权限
     */
    boolean checkPermission(Long userId, String resource, String action, String condition, Map<String, Object> context);

    /**
     * 获取用户权限列表
     * 
     * @param userId 用户ID
     * @return 权限列表
     */
    java.util.Set<String> getUserPermissions(Long userId);

    /**
     * 获取用户对指定资源的权限
     * 
     * @param userId   用户ID
     * @param resource 资源标识
     * @return 权限动作集合
     */
    java.util.Set<String> getUserResourcePermissions(Long userId, String resource);

    /**
     * 批量检查权限
     * 
     * @param userId      用户ID
     * @param permissions 权限列表（格式：resource:action）
     * @return 权限检查结果映射
     */
    Map<String, Boolean> batchCheckPermissions(Long userId, java.util.List<String> permissions);

    /**
     * 检查角色权限
     * 
     * @param roleIds  角色ID列表
     * @param resource 资源标识
     * @param action   操作动作
     * @return 是否有权限
     */
    boolean checkRolePermission(java.util.List<Long> roleIds, String resource, String action);

    /**
     * 获取引擎名称
     * 
     * @return 引擎名称
     */
    String getEngineName();

    /**
     * 获取引擎版本
     * 
     * @return 引擎版本
     */
    String getEngineVersion();

    /**
     * 是否支持指定的权限验证模式
     * 
     * @param mode 验证模式
     * @return 是否支持
     */
    boolean supports(PermissionMode mode);

    /**
     * 刷新权限缓存
     * 
     * @param userId 用户ID，null表示刷新所有用户
     */
    void refreshPermissionCache(Long userId);

    /**
     * 预热权限缓存
     * 
     * @param userIds 用户ID列表
     */
    void warmupPermissionCache(java.util.List<Long> userIds);

    /**
     * 获取权限验证统计信息
     * 
     * @return 统计信息
     */
    PermissionStats getPermissionStats();

    /**
     * 权限验证模式枚举
     */
    enum PermissionMode {
        /**
         * RBAC模式（基于角色的访问控制）
         */
        RBAC,
        
        /**
         * 规则模式（基于规则的访问控制）
         */
        RULE_BASED,
        
        /**
         * 脚本模式（基于脚本的访问控制）
         */
        SCRIPT_BASED,
        
        /**
         * 混合模式（多种模式组合）
         */
        HYBRID
    }

    /**
     * 权限统计信息
     */
    class PermissionStats {
        private long totalChecks;
        private long successChecks;
        private long failedChecks;
        private double avgResponseTime;
        private long cacheHits;
        private long cacheMisses;

        // Getters and Setters
        public long getTotalChecks() { return totalChecks; }
        public void setTotalChecks(long totalChecks) { this.totalChecks = totalChecks; }
        
        public long getSuccessChecks() { return successChecks; }
        public void setSuccessChecks(long successChecks) { this.successChecks = successChecks; }
        
        public long getFailedChecks() { return failedChecks; }
        public void setFailedChecks(long failedChecks) { this.failedChecks = failedChecks; }
        
        public double getAvgResponseTime() { return avgResponseTime; }
        public void setAvgResponseTime(double avgResponseTime) { this.avgResponseTime = avgResponseTime; }
        
        public long getCacheHits() { return cacheHits; }
        public void setCacheHits(long cacheHits) { this.cacheHits = cacheHits; }
        
        public long getCacheMisses() { return cacheMisses; }
        public void setCacheMisses(long cacheMisses) { this.cacheMisses = cacheMisses; }
    }
}
